package org.stock.agent.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.stereotype.Service;
import org.stock.agent.model.AnalysisResult;
import org.stock.agent.tools.StockTools;

@Service
@Slf4j
public class SentimentAnalyst {
    private final ChatClient openAiChatClient;
    private final ChatModel chatModel;
    private final StockTools stockTools;

    public SentimentAnalyst(ChatModel chatModel, StockTools stockTools) {

        this.chatModel = chatModel;
        this.stockTools = stockTools;

        // 构造时，可以设置 ChatClient 的参数
        // {@link org.springframework.ai.chat.client.ChatClient};
        this.openAiChatClient = ChatClient.builder(chatModel)
                // 实现 Chat Memory 的 Advisor
                // 在使用 Chat Memory 时，需要指定对话 ID，以便 Spring AI 处理上下文。
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().build()).build()
                )
                // 实现 Logger 的 Advisor
                .defaultAdvisors(
                        new SimpleLoggerAdvisor()
                )
                // 设置 ChatClient 中 ChatModel 的 Options 参数
                .defaultOptions(
                        OpenAiChatOptions.builder()
                                .topP(0.7)
                                .build()
                )
                .build();
    }
    
    public AnalysisResult analyzeSentiment(String symbol) {
        String prompt = """
            作为价值投资情绪分析师，请从长期价值投资的角度全面评估{symbol}股票的市场情绪和新闻面影响，特别关注是否存在因市场过度悲观导致的错杀机会。
            
            你需要使用以下工具获取相关信息进行分析：
            1. 使用getStockBasicInfo获取股票基础信息
            2. 使用getLatestTransaction获取最近的交易数据
            3. 使用getCapitalFlow获取资金流向数据，分析主力资金动向
            4. 使用getCurrentTime获取当前时间，确保分析的时效性
            5. 使用getRecentDividends获取近年分红数据，分析分红对市场情绪的影响
            6. 使用getRecentOfferings获取近年增发数据，分析增发对市场情绪的影响
            7. 使用getRestrictedStockUnlock获取解禁限售数据，分析解禁对市场情绪的潜在影响
            8. 使用getPerformanceForecast获取近年业绩预告数据，了解业绩预告对市场情绪的影响
            
            请从以下几个维度进行深入分析：
            1. 市场整体情绪倾向（极度乐观/乐观/中性/悲观/极度悲观）：
               - 评估当前市场对该公司的情绪是过于悲观还是合理
               - 寻找市场是否存在过度反应导致的错杀机会
            
            2. 近期交易量变化情况和异常交易分析：
               - 分析是否存在恐慌性抛售导致的异常放量下跌
               - 评估成交量萎缩是否代表市场关注度下降
            
            3. 价格波动性分析，包括日内波动和近期波动趋势：
               - 分析波动是否超出了基本面变化所能解释的范围
               - 评估是否存在非理性波动带来的投资机会
            
            4. 资金流向分析（主力资金、散户资金动向）：
               - 分析主力资金是否在低位吸筹
               - 评估散户资金流出是否过度，是否存在错杀情况
            
            5. 市场关注度分析（是否有重大新闻、公告或事件影响）：
               - 分析负面新闻是否已被市场过度解读
               - 评估公司基本面是否实际受到严重影响
            
            6. 技术指标情绪分析（如涨跌停家数、换手率等指标反映的市场情绪）：
               - 评估市场恐慌或贪婪程度
               - 分析是否存在情绪化交易机会
            
            7. 行业板块情绪影响：
               - 分析整个行业是否被市场错杀
               - 评估板块轮动对个股的影响
            
            8. 宏观经济情绪影响：
               - 分析宏观经济对市场情绪的影响
               - 评估系统性风险是否被过度定价
            
            结合获取的数据，判断市场情绪是否导致该股票被低估，
            评估当前是否为价值投资者提供良好的买入机会，
            给出适合作为逆向投资标的的可能性百分比（0-100）和详细的理由分析。
            
            特别注意：
            - 如果发现数据异常或不一致，请在分析中指出
            - 考虑市场情绪的持续性和可能的转变点
            - 结合技术面和基本面情绪进行综合判断
            - 重点关注被市场错杀的优质公司
            
            请严格按照以下JSON格式返回结果：
            {
              "analystRole": "价值投资情绪分析师",
              "symbol": "{symbol}",
              "probability": [0-100之间的数值，表示适合作为价值投资标的的概率，重点关注被市场错杀的机会],
              "reasoning": "[详细的市场情绪分析理由，至少包含300字，涵盖上述分析维度，特别说明是否存在错杀机会]",
              "confidenceLevel": "[高/中/低，基于数据质量和分析确定性]"
            }
            """;

        AnalysisResult entity = openAiChatClient.prompt(prompt + "symbol是" + symbol)
                //.user(userSpec -> userSpec.text(prompt).param("symbol", symbol))
                .tools(stockTools)
                .call()
                .entity(AnalysisResult.class);
        log.info("价值投资情绪分析师: {}", entity.getReasoning());
        return entity;
    }
}